package com.biscuit.page.basicservice.design.flow_limit.strategy;

import com.biscuit.page.basicservice.utils.BaseThreadUtil;
import com.biscuit.page.basicservice.utils.ExecutorUtil;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * @author biscuit
 * @create 2024年07月30日 15:40
 */
@Slf4j
public class LeakyBucketHandlerStrategy implements FlowLimitHandlerStrategy {

    // 漏桶总容量
    private int capacity;

    // 漏水频率
    private int rate;

    // 当前水量
    private int water;

    // 维护一个定时执行线程
    private ScheduledExecutorService executorService;

    @Override
    public void init() {
        // 允许 100 个线程等待被处理
        this.capacity = 100;

        // QPS 10
        this.rate = 10;

        // 初始等待线程数量为 0
        this.water = 0;

        // 开启一个维护线程进行水量的定期维护
        this.executorService = Executors.newSingleThreadScheduledExecutor();
        this.executorService.scheduleAtFixedRate(() -> {
            this.water = Math.min(0, this.water - 10);
        },0 , 1, TimeUnit.SECONDS);

    }

    @Override
    public synchronized boolean attempt() {
        // 唤醒正在阻塞的线程
        this.notifyAll();

        // 判断当前水量是否超出阈值
        if (this.water > this.capacity) {
            return false;
        }

        // 当前水量 + 1
        this.water ++;

        // 判断当前水量是否超出每秒的可处理阈值
        if (this.water > this.rate) {

            // 当前线程睡眠，等待唤醒
            try {
                this.wait(100);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }

            // 递归调用，自旋
            this.attempt();
        }

        // 放行
        return true;
    }

}
